package cn.com.pajx.pajx_visitor_v3.ui.fragment;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.hardware.Camera;
import android.os.Bundle;
import android.view.OrientationEventListener;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import butterknife.BindView;
import butterknife.OnClick;
import cn.com.pajx.pajx_visitor_v3.R;
import cn.com.pajx.pajx_visitor_v3.base.BaseFragment;
import cn.com.pajx.pajx_visitor_v3.utils.DateUtil;
import cn.com.pajx.pajx_visitor_v3.utils.LogUtils;
import cn.com.pajx.pajx_visitor_v3.utils.MediaStoreUtil;
import cn.com.pajx.pajx_visitor_v3.utils.ToastUtil;

/**
 * 学择拜访对象页面
 * create an instance of this fragment.
 */
@SuppressLint("NonConstantResourceId")
public class FaceGatherFragment extends BaseFragment implements SurfaceHolder.Callback {

    @BindView(R.id.view_gather_example)
    RelativeLayout viewGatherExample;
    @BindView(R.id.view_gather)
    RelativeLayout viewGather;
    @BindView(R.id.preview_sfv)
    SurfaceView previewSfv;
    @BindView(R.id.tv_gather_tips)
    TextView tvGatherTips;
    @BindView(R.id.tv_take_photo)
    TextView tvTakePhoto;
    @BindView(R.id.iv_mask)
    ImageView ivMask;
    @BindView(R.id.view_preview)
    LinearLayout viewPreview;

    private Camera mCamera;
    private SurfaceHolder mHolder;
    private OnFunctionListener onFunctionListener;
    private int degrees = 0;
    private Bitmap matrixBitmap;//需要保存的照片

    public FaceGatherFragment() {
    }

    public static FaceGatherFragment newInstance() {
        FaceGatherFragment fragment = new FaceGatherFragment();
        return fragment;
    }

    @Override
    protected void beforeInitHead() {

    }

    @Override
    protected int getLayoutId() {
        return R.layout.fragment_face_gather;
    }

    @Override
    protected void initView(View view, Bundle savedInstanceState) {
        initSurfaceHolder();
    }

    /**
     * 初始化Camera
     */
    private void initCamera() {
        try {
            LogUtils.e("frontCameraId=" + Camera.CameraInfo.CAMERA_FACING_BACK);
            mCamera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);//1:采集指纹的摄像头. 0:拍照的摄像头.
            mCamera.setPreviewDisplay(mHolder);
        } catch (Exception e) {
            LogUtils.e("Exception=" + e.getMessage());
            ToastUtil.toast("相机打开失败");
            onClickBack();
            e.printStackTrace();
        }
    }

    /**
     * 初始化SurfaceHolder
     */
    private void initSurfaceHolder() {
        mHolder = previewSfv.getHolder();
        mHolder.addCallback(this);
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        DetectScreenOrientation detectScreenOrientation = new DetectScreenOrientation(mContext);
        detectScreenOrientation.enable();
    }

    @Override
    public void surfaceCreated(SurfaceHolder surfaceHolder) {
        initCamera();
    }

    @Override
    public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
        setCameraParams();
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
        releaseCamera();
    }


    /**
     * 设置相机参数
     */
    private void setCameraParams() {
        try {
            if (mCamera == null) {
                ToastUtil.toast("相机打开失败");
                return;
            }
            Camera.Parameters parameters = mCamera.getParameters();
            initDisplayOrientation(parameters);
            // 获取摄像头支持最合适的分辨率
            Camera.Size preSize = findBestPreviewSize();
            parameters.setPreviewSize(preSize.width, preSize.height);
            parameters.setPictureSize(preSize.width, preSize.height);
            LogUtils.e("preSize.width=" + preSize.width + "--preSize.height=" + preSize.height);

            parameters.setJpegQuality(100); // 设置照片质量
            if (parameters.getSupportedFocusModes().contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {
                parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);// 连续对焦模式
            }
            mCamera.setParameters(parameters);
            mCamera.cancelAutoFocus();//自动对焦
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 找出最适合的预览界面分辨率
     *
     * @return SIZE
     */
    private Camera.Size findBestPreviewSize() {
        Camera.Parameters cameraParameters = mCamera.getParameters();
        Camera.Size defaultPreviewSize = cameraParameters.getPreviewSize();

        List<Camera.Size> rawSupportedSizes = cameraParameters.getSupportedPreviewSizes();
        if (rawSupportedSizes == null) {
            return defaultPreviewSize;
        }

        // 按照分辨率从大到小排序
        List<Camera.Size> supportedPreviewResolutions = new ArrayList<>(rawSupportedSizes);
        Collections.sort(supportedPreviewResolutions, (a, b) -> {
            int aPixels = a.width * a.height;
            int bPixels = b.width * b.height;
            return Integer.compare(bPixels, aPixels);
        });
        // 移除不符合条件的分辨率
        Iterator<Camera.Size> it = supportedPreviewResolutions.iterator();
        while (it.hasNext()) {
            Camera.Size supportedPreviewResolution = it.next();
            int width = supportedPreviewResolution.width;
            int height = supportedPreviewResolution.height;
            // 移除低于下限的分辨率，尽可能取高分辨率
            int MIN_PREVIEW_PIXELS = 1280 * 720;
            if (width * height < MIN_PREVIEW_PIXELS) {
                it.remove();
            }
        }

        // 如果没有找到合适的，并且还有候选的像素，则设置其中最大比例的，对于配置比较低的机器不太合适
        if (!supportedPreviewResolutions.isEmpty()) {
            return supportedPreviewResolutions.get(0);
        }
        // 没有找到合适的，就返回默认的
        return defaultPreviewSize;
    }

    /**
     * 相机角度设置
     *
     * @param parameters 相机参数
     */
    private void initDisplayOrientation(Camera.Parameters parameters) {
        int orientation = judgeScreenOrientation();
        LogUtils.e("orientation=" + orientation);
        switch (orientation) {
            case Surface.ROTATION_0:
                degrees = 90;
                break;
            case Surface.ROTATION_90:
                degrees = 0;
                break;
            case Surface.ROTATION_180:
                degrees = 180;
                break;
            case Surface.ROTATION_270:
                degrees = 270;
                break;
        }
        int result = (new Camera.CameraInfo().orientation + degrees) % 360;
        result = (360 - result) % 360;
        LogUtils.e("result=" + result);
        mCamera.setDisplayOrientation(result);
        parameters.setRotation(result);
    }

    /**
     * 判断屏幕方向
     *
     * @return 0：竖屏 1：左横屏 2：反向竖屏 3：右横屏
     */
    private int judgeScreenOrientation() {
        return requireActivity().getWindowManager().getDefaultDisplay().getRotation();
    }

    /**
     * 用来监测左横屏和右横屏切换时旋转摄像头的角度
     */
    private class DetectScreenOrientation extends OrientationEventListener {
        DetectScreenOrientation(Context context) {
            super(context);
        }

        @Override
        public void onOrientationChanged(int orientation) {
            if (260 < orientation && orientation < 290) {
                setCameraParams();
            } else if (80 < orientation && orientation < 100) {
                setCameraParams();
            }
        }
    }

    /**
     * 释放Camera
     */
    private void releaseCamera() {
        if (mCamera != null) {
            mCamera.stopPreview();
            mCamera.release();
            mCamera = null;
        }
    }

    @SuppressLint("NotifyDataSetChanged")
    @OnClick({R.id.tv_start, R.id.tv_take_photo, R.id.tv_reset, R.id.tv_save, R.id.iv_close})
    public void onViewClicked(View view) {
        switch (view.getId()) {
            case R.id.iv_close:
                dismiss();
                break;
            case R.id.tv_start:
                mCamera.startPreview();
                viewGather.setVisibility(View.VISIBLE);
                viewGatherExample.setVisibility(View.INVISIBLE);
                break;
            case R.id.tv_take_photo:
                takePicture();
                tvGatherTips.setText("请确认照片符合要求后保存");
                ivMask.setVisibility(View.GONE);
                tvTakePhoto.setVisibility(View.GONE);
                viewPreview.setVisibility(View.VISIBLE);
                break;
            case R.id.tv_reset:
                mCamera.startPreview();
                tvGatherTips.setText("请正脸面对摄像头，头部边缘对齐头像框后点击拍照");
                ivMask.setVisibility(View.VISIBLE);
                tvTakePhoto.setVisibility(View.VISIBLE);
                viewPreview.setVisibility(View.GONE);
                break;
            case R.id.tv_save:
                String image_name = "gather_img_" + DateUtil.getCurrentTime();
                MediaStoreUtil.saveBitmapToMediaStore(mContext, MediaStoreUtil.FACE_GATHER_DIR, image_name, matrixBitmap);
                String img_path = MediaStoreUtil.checkImageFromMediaStore(mContext, MediaStoreUtil.FACE_GATHER_DIR, image_name);
                if (onFunctionListener != null) onFunctionListener.onChoose(img_path);
                dismiss();
                break;
        }
    }

    /**
     * 拍照
     */
    private void takePicture() {
        mCamera.takePicture(() -> {
        }, null, (bytes, camera) -> {
            Bitmap originBitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
            matrixBitmap = rotateBitmap(degrees, originBitmap);
            //原始照片的宽高
            float width = matrixBitmap.getWidth();
            float height = matrixBitmap.getHeight();
            LogUtils.e("width=" + width + "==height=" + height);
            //释放相机资源
            if (mCamera != null) {
                mCamera.stopPreview();
            }
        });
    }

    /**
     * 旋转拍照后的图片
     *
     * @param angle  角度
     * @param bitmap 原图
     * @return 旋转后的图片
     */
    public Bitmap rotateBitmap(int angle, Bitmap bitmap) {
        //旋转图片 动作
        Matrix matrix = new Matrix();
        matrix.postRotate(angle);
        // 创建新的图片
        Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0,
                bitmap.getWidth(), bitmap.getHeight(), matrix, true);
        return resizedBitmap;
    }

    public interface OnFunctionListener {
        void onChoose(String path);
    }

    public void setOnFunctionListener(OnFunctionListener onFunctionListener) {
        this.onFunctionListener = onFunctionListener;
    }
}